#if !defined(__HTTP_SERVER)
#define __HTTP_SERVER

#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <boost/asio/strand.hpp>
#include <boost/config.hpp>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <map>

#include <functional>
#include "HttpSession.hpp"

class HttpServer : public boost::asio::io_context, public boost::enable_shared_from_this<HttpSession>
{
public:
    typedef HttpSession::RequestHandler RequestHandler;

private:
    std::string doc_root;
    std::size_t thread_pool_size;
    std::vector<std::thread> thread_pool;
    boost::asio::executor_work_guard<boost::asio::io_context::executor_type> work_guard;

    boost::asio::ip::tcp::acceptor acceptor;

    std::map<std::string, RequestHandler> get_handlers;
    std::map<std::string, RequestHandler> post_handlers;

public:
    HttpServer(
        std::int32_t port, std::string &doc_root, std::size_t thread_pool_size = 4);
    ~HttpServer();

    void get(std::string target, RequestHandler handler);
    void post(std::string target, RequestHandler handler);
    RequestHandler &get(std::string target);
    RequestHandler &post(std::string target);

private:
    void join();

private:
    void do_accept();
};

#endif // __HTTP_SERVER
